#ifndef _debugging_h_
#define _debugging_h_

// debugging.h
//
// Debugging related classes


#include <bitset>

namespace simple{
    //
    // Debug
    //

    // DEBUGGING(level,statement) is used to define one or more c++
    // statements to run when the current debugging level is >= the
    // specified level. You can generate production releases with this
    // code enabled, or you can #define NODEBUG to compile-out the code.
    //
    // For single line statements you might try this:
    //     DEBUGGING(1, cdebug << "Hello World" << std::endl;)
    //
    // For longer statements, this looks more natrual:
    //     DEBUGGING(1, {
    //         for (int i=0; i<10; i++)
    //             cdebug << "Hello World" << std::endl;
    //     })
    //

    #ifdef NODEBUG
    #define DEBUGGING(level,statements)
    #else
    #define DEBUGGING(level,statements)          \
        if (Debug::gOnly().isDebug(level)) {     \
            statements                           \
        }
    #endif


    #if 0 // Version of Debug that uses values to control debugging

    class Debug
    {
    public:
        static Debug& gOnly ();

        int  debug   ()      { return _debug;}
        int  debug   (int d) { int cur = _debug; _debug = d; return cur;}
        // Get/set the global debugging level

        bool isDebug (int level) { return _debug >= level;}
        // Returns true if this level is enabled for debugging.

    private:
        static Debug* _sOnly;
        int _debug;

        Debug ();
    };

    #endif


    // This version uses bit settings, but no error checking is used
    class Debug
    {
    public:
        static Debug& gOnly ();

        bool  debug   (int pos) { return _debug.test (pos);}
        bool  debug   (int pos, bool value) 
        { bool cur = _debug.test (pos); 
            if (value)
                _debug.set (pos);
            else
                _debug.reset (pos);
            return cur;
        }
        // Get/set the global debugging level

        bool set   (int pos)
        {
            bool cur = _debug.test (pos);
            _debug.set (pos); return cur;
        }
        bool clear (int pos) {
            bool cur = _debug.test (pos);
            _debug.reset (pos); return cur;
        }
        // Set/clear a specific bit and return the old state

        void reset () { _debug.reset ();}
        // Turns off all debugging

        bool isDebug (int pos) { return _debug.test (pos);}
        // Returns true if this level is enabled for debugging.

    private:
        static Debug* _sOnly;
        std::bitset<32> _debug;        // 32 is an arbitrary value, you can raise it or lower it

        Debug ();
    };

}


#endif // _debugging_h_
